<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #wrap {
        position: relative;
        margin-left: 300px;
      }
      #wrap > div {
        position: absolute;
        width: 100px;
        height: 100px;
        border-radius: 10px;
        text-align: center;
        line-height: 100px;
        font-size: 30px;
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <div id="wrap"></div>
    <script>
      //js生成结构行列结构 生成随机颜色 生成left和top值 行的top值一样 列的left值一样  格子里有文本

      var Surface = document.querySelector("#wrap");

      var mg = 10;

      //二维数组  数组里的元素依然是一个数组
      var arr = [
        ["A", "B", "C"],
        ["D", "E", "F"],
        ["G", "H", "I"],
      ];
      // console.log(arr.length);

      for (var i = 0; i < 3; i++) {
        //行
        for (var j = 0; j < 3; j++) {
          //列
          var oDiv = document.createElement("div");
          Surface.appendChild(oDiv);
          oDiv.style.top = i * (oDiv.offsetHeight + mg) + "px";
          oDiv.style.left = j * (oDiv.offsetWidth + mg) + "px";
          oDiv.style.backgroundColor =
            "rgb(" +
            parseInt(Math.random() * 256) +
            "," +
            parseInt(Math.random() * 256) +
            "," +
            parseInt(Math.random() * 256) +
            ")";

          //console.log(i * 3 + j);
          //oDiv.innerText = arr[i * 3 + j];
          oDiv.innerText = arr[i][j];
        }
      }

      //拖拽 三要素  mouseup  取一组距离  找最小值及索引  交换位置
      var aDiv = Surface.querySelectorAll("div");
      aDiv.forEach(function (item) {
        item.onmousedown = function (e) {
          e.preventDefault();
          var x = e.offsetX;
          var y = e.offsetY;
          var cloneItem = item.cloneNode(); //克隆节点，做一个占位，因为后续比较距离的时候，还要考虑拖拽对象和克隆节点之间的距离
          cloneItem.style.border = "1px dashed #cecece";

          Surface.replaceChild(cloneItem, item); //确保拖拽对象不和自身比较取距离，而是和克隆节点取距离

          Surface.appendChild(item);
          item.style.zIndex = 1; //改变层级，不至于被其他格子盖住
          document.onmousemove = function (e) {
            e.preventDefault();
            var l = e.clientX - x - Surface.offsetLeft;
            var t = e.clientY - y - Surface.offsetTop;
            item.style.left = l + "px";
            item.style.top = t + "px";
          };
          document.onmouseup = function () {
            //保存9个距离的数组
            var arrDis = [];
            var aDiv = Surface.querySelectorAll("div"); //这个时候有10个元素
            for (var i = 0; i < aDiv.length - 1; i++) {
              //把自身去除了，因为不需要和自身比
              var disx = item.offsetLeft - aDiv[i].offsetLeft; //水平方向的直角边
              var disy = item.offsetTop - aDiv[i].offsetTop; //竖直方向的直角边
              var dis = Math.sqrt(disx * disx + disy * disy); //勾股定理
              arrDis.push(dis);
            }
            //取距离最小的索引
            var minIndex = 0;
            for (var i = 1; i < arrDis.length; i++) {
              if (arrDis[minIndex] > arrDis[i]) {
                minIndex = i; //循环结束后，minIndex就是最小值索引
              }
            }

            //交换
            item.style.left = aDiv[minIndex].style.left;
            item.style.top = aDiv[minIndex].style.top;

            aDiv[minIndex].style.left = cloneItem.style.left;
            aDiv[minIndex].style.top = cloneItem.style.top;

            cloneItem.remove();

            document.onmousemove = null;
            document.onmouseup = null;
          };
        };
      });
    </script>
  </body>
</html>
